package main

//
//import (
//	"bytes"
//	"crypto/md5"
//	"encoding/binary"
//	"fmt"
//	"github.com/google/gopacket"
//	"github.com/google/gopacket/layers"
//	"github.com/google/gopacket/pcap"
//	"log"
//	"math/big"
//	"net"
//	"strings"
//	"sync"
//	"time"
//)
//
//var (
//	// debug  bool
//	rwlock           sync.RWMutex
//	pblackTargetList *[1 << 29]uint8
//	preverseSeqList  *[1 << 16]uint32
//	lock             sync.Mutex
//	statsListMap     map[string]int
//)
//
//func main() {
//	statsListMap = make(map[string]int)
//	initTargetList()
//	// Open connection
//	handleMirror, errHandleMirror := pcap.OpenLive(
//		"\\Device\\NPF_{C6571165-98E0-458B-B665-61F7D78A00CE}", // network device
//		int32(65535),
//		true,
//		time.Microsecond,
//	)
//	if errHandleMirror != nil {
//		fmt.Println("Mirror Handler error", errHandleMirror.Error())
//		return
//	}
//
//	//init send packet channel
//	c := make(chan [2]gopacket.Packet)
//
//	handleMgt, errHandleMgt := pcap.OpenLive(
//		"\\Device\\NPF_{C6571165-98E0-458B-B665-61F7D78A00CE}", // network device
//		int32(65535),
//		false,
//		time.Microsecond,
//	)
//	if errHandleMgt != nil {
//		fmt.Println("MGT Handler error", errHandleMgt.Error())
//	}
//
//	//发包
//	go sendResetPacket(handleMgt, c)
//
//	packetSource := gopacket.NewPacketSource(handleMirror, handleMirror.LinkType())
//	for packet := range packetSource.Packets() {
//		go analysePacket(packet, handleMirror, c)
//	}
//
//}
//
//func initTargetList() {
//	//1.0
//	preverseSeqList = new([1 << 16]uint32)
//	//2.0
//	pblackTargetList = new([1 << 29]uint8)
//	target := "180.101.49.12"
//	target8 := ipStringToInt64(target) / 8
//	targetmod8 := ipStringToInt64(target) % 8
//	(*pblackTargetList)[target8] = 1 << uint8(targetmod8)
//}
//
//// 解析数据包
//func analysePacket(packet gopacket.Packet, handleMgt *pcap.Handle, c chan [2]gopacket.Packet) {
//	ethLayer := packet.Layer(layers.LayerTypeEthernet)
//	ipLayer := packet.Layer(layers.LayerTypeIPv4)
//	if ipLayer != nil {
//		tcpLayer := packet.Layer(layers.LayerTypeTCP)
//		libpcap, _ := tcpLayer.(*layers.TCP)
//		ip, _ := ipLayer.(*layers.IPv4)
//		eth, _ := ethLayer.(*layers.Ethernet)
//		if tcpLayer != nil {
//			if (libpcap.SYN && libpcap.ACK) && !(libpcap.RST || libpcap.FIN || libpcap.PSH) {
//				//第二次握手
//				analyseSecondHandShake(eth, ip, libpcap)
//				return
//			} else if (libpcap.PSH && libpcap.ACK) && !(libpcap.RST || libpcap.FIN || libpcap.SYN) {
//				//握手完成开始推送数据
//				socketMD5 := socketToMD5Uint16(ip.SrcIP, uint16(libpcap.SrcPort), ip.DstIP, uint16(libpcap.DstPort))
//				reverseSeq := (*preverseSeqList)[socketMD5]
//				(*preverseSeqList)[socketMD5] = 0
//				if reverseSeq != 0 {
//					//marked by 2nd handshake
//					if libpcap.Seq == (reverseSeq + uint32(1)) {
//						//1st request reverse, return
//						return
//					} else {
//						fmt.Println("1st request - get socket md5 and previous seq: ", socketMD5, reverseSeq)
//						//正向重置包
//						resetPacketForward := forgeResetForward(eth, ip, libpcap)
//						//反向重置包
//						resetPacketReverse := forgeResetReverse(eth, ip, libpcap, uint16(len(libpcap.Payload)))
//						fmt.Printf("1st request reverse - Attacking %s and %s\n", ip.DstIP, ip.SrcIP)
//						c <- [2]gopacket.Packet{resetPacketReverse, resetPacketForward}
//						fmt.Printf("1st request forward - Attacking %s and %s\n", ip.SrcIP, ip.DstIP)
//					}
//				}
//			}
//		}
//
//	}
//}
//
////解析第二次握手
//func analyseSecondHandShake(eth *layers.Ethernet, ip *layers.IPv4, libpcap *layers.TCP) {
//	//匹配白名单
//	log.Println("analyseSecondHandShake")
//	if matchIPWithTargetList(pblackTargetList, ipStringToInt64(ip.SrcIP.String())) {
//		fmt.Println("2nd handshake - Dst IP is black: ", ip.DstIP.String())
//		socketMD5 := socketToMD5Uint16(ip.DstIP, uint16(libpcap.DstPort), ip.SrcIP, uint16(libpcap.SrcPort))
//		(*preverseSeqList)[socketMD5] = libpcap.Seq
//		fmt.Println("2nd handshake - restore socket md5 and seq: ", socketMD5, libpcap.Seq)
//		time.Sleep(time.Millisecond * 100)
//		(*preverseSeqList)[socketMD5] = 0
//		hitTarget(ip.SrcIP.String())
//		return
//	}
//
//}
//
////IP 在ptargetList内返回true
//func matchIPWithTargetList(ptargetList *[1 << 29]uint8, ip int64) bool {
//	ip8 := ip >> 3                    // ip / 8
//	ipmod8 := uint8(1 << uint8(ip&7)) // ip % 8
//	rwlock.RLock()
//	match := (*ptargetList)[ip8] & ipmod8
//	rwlock.RUnlock()
//	if match == 0 {
//		return false
//	} else if match > 0 {
//		return true
//	}
//	return false
//}
//
//// 将字符串转成int
//func ipStringToInt64(s string) int64 {
//	ret := big.NewInt(0)
//	ret.SetBytes(net.ParseIP(s).To4())
//	return ret.Int64()
//}
//
//// 将目的IP 端口,源IP端口转成uint
//func socketToMD5Uint16(srcIP []byte, srcPort uint16, dstIP []byte, dstPort uint16) uint16 {
//	bytebuf := bytes.NewBuffer([]byte{})
//	binary.Write(bytebuf, binary.BigEndian, srcIP)
//	binary.Write(bytebuf, binary.BigEndian, srcPort)
//	binary.Write(bytebuf, binary.BigEndian, dstIP)
//	binary.Write(bytebuf, binary.BigEndian, dstPort)
//
//	retByte := md5.Sum(bytebuf.Bytes())
//	ret := binary.BigEndian.Uint16(retByte[:])
//	//ret = ret & ((1 << 18) - 1)
//	return ret
//}
//
//func hitTarget(ipAddress string) {
//	lock.Lock()
//	value, exist := statsListMap[ipAddress]
//	if exist == false {
//		statsListMap[ipAddress] = 1
//		lock.Unlock()
//		return
//	}
//	statsListMap[ipAddress] = value + 1
//	lock.Unlock()
//	return
//}
//
////重置包
//func forgeResetForward(eth *layers.Ethernet, ip *layers.IPv4, libpcap *layers.TCP) gopacket.Packet {
//	//eth
//	eth.EthernetType = 0x0800
//	ip.Id = 0x0100
//	ip.Flags = 0x0000
//
//	options := gopacket.SerializeOptions{
//		ComputeChecksums: true,
//		FixLengths:       true,
//	}
//	//libpcap
//
//	libpcap.RST = true
//	libpcap.NS = false
//	libpcap.CWR = false
//	libpcap.ECE = false
//	libpcap.URG = false
//	libpcap.PSH = false
//	libpcap.SYN = false
//	libpcap.FIN = false
//	libpcap.ACK = false
//	libpcap.Window = 32767
//	//	libpcap.Seq = libpcap.Seq + uint32(1)
//	libpcap.Ack = uint32(1)
//	libpcap.Options = []layers.TCPOption{
//		layers.TCPOption{
//			OptionType:   layers.TCPOptionKind(layers.TCPOptionKindWindowScale),
//			OptionLength: 0x03,
//			OptionData:   []byte{0x0a},
//		},
//		layers.TCPOption{
//			OptionType:   layers.TCPOptionKind(layers.TCPOptionKindNop),
//			OptionLength: 0x01,
//		},
//		layers.TCPOption{
//			OptionType:   layers.TCPOptionKind(layers.TCPOptionKindMSS),
//			OptionLength: 0x04,
//			OptionData:   []byte{0x01, 0x09},
//		},
//		layers.TCPOption{
//			OptionType:   layers.TCPOptionKind(layers.TCPOptionKindTimestamps),
//			OptionLength: 0x0a,
//			OptionData:   []byte{0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00},
//		},
//		layers.TCPOption{
//			OptionType: layers.TCPOptionKind(layers.TCPOptionKindEndList),
//		},
//	}
//
//	libpcap.SetNetworkLayerForChecksum(ip)
//
//	//assemble forward packet
//	resetPacketBuffer := gopacket.NewSerializeBuffer()
//	//fmt.Println(srcMac, dstMac)
//	err := gopacket.SerializeLayers(resetPacketBuffer, options,
//		eth,
//		ip,
//		libpcap,
//	)
//	//err := gopacket.SerializePacket(resetPacketBuffer, options, packet)
//	if err != nil {
//		panic(err)
//	}
//	resetPacket := gopacket.NewPacket(resetPacketBuffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
//	fmt.Println("1st request forward - reset packet: ", resetPacket)
//	return resetPacket
//}
//
////反向重置包
//func forgeResetReverse(eth *layers.Ethernet, ip *layers.IPv4, libpcap *layers.TCP, lenPayload uint16) gopacket.Packet {
//	options := gopacket.SerializeOptions{
//		ComputeChecksums: true,
//		FixLengths:       true,
//	}
//	//libpcap.Seq = reverseSeq + uint32(1)
//	libpcap.Seq = libpcap.Ack
//	//libpcap.Ack = uint32(1) + uint32(lenPayload)
//	libpcap.Ack = libpcap.Seq
//	eth.SrcMAC, eth.DstMAC = eth.DstMAC, eth.SrcMAC
//	libpcap.SrcPort, libpcap.DstPort = libpcap.DstPort, libpcap.SrcPort
//	ip.SrcIP, ip.DstIP = ip.DstIP, ip.SrcIP
//
//	libpcap.SetNetworkLayerForChecksum(ip)
//	//assemble forward packet
//	resetPacketBuffer := gopacket.NewSerializeBuffer()
//	//fmt.Println(srcMac, dstMac)
//	err := gopacket.SerializeLayers(resetPacketBuffer, options,
//		eth,
//		ip,
//		libpcap,
//	)
//	//err := gopacket.SerializePacket(resetPacketBuffer, options, packet)
//	if err != nil {
//		panic(err)
//	}
//	resetPacket := gopacket.NewPacket(resetPacketBuffer.Bytes(), layers.LayerTypeEthernet, gopacket.Default)
//	fmt.Println("1st request reverse - reset packet: ", resetPacket)
//	return resetPacket
//}
//
////从chan 内取出包发送
//func sendResetPacket(handleMgt *pcap.Handle, c chan [2]gopacket.Packet) {
//	for {
//		packets := <-c
//		if err := handleMgt.WritePacketData(packets[0].Data()); err != nil {
//			fmt.Println("Send error", err.Error())
//		}
//		if err := handleMgt.WritePacketData(packets[1].Data()); err != nil {
//			fmt.Println("Send error", err.Error())
//		}
//		log.Println("sendResetPacket")
//	}
//}
//
//func ipIntervalToTargetList(intervals string, ptargetList *[1 << 29]uint8) *[1 << 29]uint8 {
//	//去除单行属性两端的空格
//	intervals = strings.TrimSpace(intervals)
//
//	//判断等号=在该行的位置
//	intervalIndex := strings.Index(intervals, "-")
//	if intervalIndex < 0 {
//		fmt.Println("fail to get index")
//		return ptargetList
//	}
//	//取得等号左边的start值，判断是否为空
//	startString := strings.TrimSpace(intervals[:intervalIndex])
//	if len(startString) == 0 {
//		fmt.Println("fail to get start string")
//		return ptargetList
//	}
//
//	//取得等号右边的end值，判断是否为空
//	endString := strings.TrimSpace(intervals[intervalIndex+1:])
//	if len(endString) == 0 {
//		fmt.Println("fail to get end string")
//		return ptargetList
//	}
//
//	start := ipStringToInt64(startString)
//	end := ipStringToInt64(endString)
//
//	for i := start; i < (end + 1); i++ {
//		(*ptargetList)[(i / 8)] = (1 << uint8(i%8))
//	}
//
//	return ptargetList
//}
